रिॲक्टच्या रेंडरिंग प्रक्रियेचा सखोल अभ्यास, कंपोनेंट लाइफसायकल, ऑप्टिमायझेशन तंत्र आणि कार्यक्षम ॲप्लिकेशन्स तयार करण्यासाठी सर्वोत्तम पद्धती.
रिॲक्ट रेंडर: कंपोनेंट रेंडरिंग आणि लाइफसायकल व्यवस्थापन
रिॲक्ट, यूजर इंटरफेस तयार करण्यासाठी एक लोकप्रिय जावास्क्रिप्ट लायब्ररी आहे, जी कंपोनेंट्स प्रदर्शित आणि अपडेट करण्यासाठी एका कार्यक्षम रेंडरिंग प्रक्रियेवर अवलंबून असते. रिॲक्ट कंपोनेंट्स कसे रेंडर करते, त्यांचे लाइफसायकल कसे व्यवस्थापित करते आणि कार्यक्षमता कशी ऑप्टिमाइझ करते हे समजून घेणे, मजबूत आणि स्केलेबल ॲप्लिकेशन्स तयार करण्यासाठी महत्त्वाचे आहे. हा सर्वसमावेशक मार्गदर्शक या संकल्पनांचा तपशीलवार शोध घेतो, जगभरातील डेव्हलपर्ससाठी व्यावहारिक उदाहरणे आणि सर्वोत्तम पद्धती प्रदान करतो.
रिॲक्ट रेंडरिंग प्रक्रिया समजून घेणे
रिॲक्टच्या कार्याचा गाभा त्याच्या कंपोनेंट-आधारित आर्किटेक्चर आणि व्हर्च्युअल DOM मध्ये आहे. जेव्हा एखाद्या कंपोनेंटचे स्टेट (state) किंवा प्रॉप्स (props) बदलतात, तेव्हा रिॲक्ट थेट प्रत्यक्ष DOM मध्ये बदल करत नाही. त्याऐवजी, ते DOM चे एक आभासी प्रतिनिधित्व तयार करते, ज्याला व्हर्च्युअल DOM म्हणतात. त्यानंतर, रिॲक्ट व्हर्च्युअल DOM ची मागील आवृत्तीशी तुलना करते आणि प्रत्यक्ष DOM अपडेट करण्यासाठी आवश्यक बदलांचा किमान संच ओळखते. या प्रक्रियेला रिकॉन्सिलिएशन (reconciliation) म्हणतात, ज्यामुळे कार्यक्षमतेत लक्षणीय सुधारणा होते.
व्हर्च्युअल DOM आणि रिकॉन्सिलिएशन
व्हर्च्युअल DOM हे प्रत्यक्ष DOM चे एक हलके, इन-मेमरी प्रतिनिधित्व आहे. हे प्रत्यक्ष DOM पेक्षा हाताळायला खूप जलद आणि अधिक कार्यक्षम आहे. जेव्हा एखादा कंपोनेंट अपडेट होतो, तेव्हा रिॲक्ट एक नवीन व्हर्च्युअल DOM ट्री तयार करतो आणि त्याची मागील ट्रीशी तुलना करतो. या तुलनेमुळे रिॲक्टला हे ठरवता येते की प्रत्यक्ष DOM मधील कोणत्या विशिष्ट नोड्सना अपडेट करण्याची आवश्यकता आहे. त्यानंतर रिॲक्ट हे किमान अपडेट्स प्रत्यक्ष DOM वर लागू करतो, ज्यामुळे एक जलद आणि अधिक कार्यक्षम रेंडरिंग प्रक्रिया होते.
हे सोपे उदाहरण विचारात घ्या:
परिस्थिती: एका बटणावर क्लिक केल्याने स्क्रीनवर दिसणारा काउंटर अपडेट होतो.
रिॲक्टशिवाय: प्रत्येक क्लिकमुळे संपूर्ण DOM अपडेट होऊ शकते, ज्यामुळे संपूर्ण पृष्ठ किंवा त्याचे मोठे भाग पुन्हा रेंडर होतात, परिणामी कार्यक्षमता मंदावते.
रिॲक्टसह: फक्त व्हर्च्युअल DOM मधील काउंटर व्हॅल्यू अपडेट केली जाते. रिकॉन्सिलिएशन प्रक्रिया हा बदल ओळखते आणि तो प्रत्यक्ष DOM मधील संबंधित नोडवर लागू करते. बाकीचे पृष्ठ अपरिवर्तित राहते, ज्यामुळे एक सहज आणि प्रतिसाद देणारा वापरकर्ता अनुभव मिळतो.
रिॲक्ट बदल कसे ठरवते: डिफरिंग अल्गोरिदम
रिॲक्टचा डिफरिंग अल्गोरिदम हा रिकॉन्सिलिएशन प्रक्रियेचा गाभा आहे. तो नवीन आणि जुन्या व्हर्च्युअल DOM ट्रीजमधील फरक ओळखण्यासाठी त्यांची तुलना करतो. तुलना ऑप्टिमाइझ करण्यासाठी हा अल्गोरिदम अनेक गृहितके वापरतो:
- वेगवेगळ्या प्रकारांचे दोन एलिमेंट्स वेगवेगळे ट्री तयार करतील. जर मूळ एलिमेंट्सचे प्रकार वेगवेगळे असतील (उदा. <div> चे <span> मध्ये बदलणे), तर रिॲक्ट जुने ट्री अनमाउंट करेल आणि नवीन ट्री सुरवातीपासून तयार करेल.
- एकाच प्रकारच्या दोन एलिमेंट्सची तुलना करताना, रिॲक्ट बदल आहेत की नाही हे पाहण्यासाठी त्यांच्या ॲट्रिब्यूट्सकडे पाहतो. जर फक्त ॲट्रिब्यूट्स बदलले असतील, तर रिॲक्ट सध्याच्या DOM नोडचे ॲट्रिब्यूट्स अपडेट करेल.
- रिॲक्ट लिस्ट आयटम्सना अद्वितीयपणे ओळखण्यासाठी 'की' (key) प्रॉपचा वापर करतो. 'की' प्रॉप प्रदान केल्याने रिॲक्टला संपूर्ण लिस्ट पुन्हा रेंडर न करता कार्यक्षमतेने लिस्ट अपडेट करता येते.
ही गृहितके समजून घेतल्याने डेव्हलपर्सना अधिक कार्यक्षम रिॲक्ट कंपोनेंट्स लिहिण्यास मदत होते. उदाहरणार्थ, लिस्ट रेंडर करताना 'की' वापरणे कार्यक्षमतेसाठी अत्यंत महत्त्वाचे आहे.
रिॲक्ट कंपोनेंट लाइफसायकल
रिॲक्ट कंपोनेंट्सचे एक निश्चित लाइफसायकल असते, ज्यात कंपोनेंटच्या अस्तित्वातील विशिष्ट टप्प्यांवर कॉल केल्या जाणाऱ्या मेथड्सची एक मालिका असते. या लाइफसायकल मेथड्स समजून घेतल्याने डेव्हलपर्सना कंपोनेंट्स कसे रेंडर, अपडेट आणि अनमाउंट करायचे हे नियंत्रित करता येते. हुक्स (Hooks) च्या परिचयानंतरही, लाइफसायकल मेथड्स अजूनही संबंधित आहेत आणि त्यांची मूळ तत्त्वे समजून घेणे फायदेशीर आहे.
क्लास कंपोनेंट्समधील लाइफसायकल मेथड्स
क्लास-आधारित कंपोनेंट्समध्ये, लाइफसायकल मेथड्सचा उपयोग कंपोनेंटच्या आयुष्यातील वेगवेगळ्या टप्प्यांवर कोड कार्यान्वित करण्यासाठी केला जातो. येथे मुख्य लाइफसायकल मेथड्सचे अवलोकन आहे:
constructor(props): कंपोनेंट माउंट होण्यापूर्वी कॉल केली जाते. याचा उपयोग स्टेट सुरू करण्यासाठी आणि इव्हेंट हँडलर्सना बाइंड करण्यासाठी केला जातो.static getDerivedStateFromProps(props, state): सुरुवातीच्या माउंट आणि त्यानंतरच्या अपडेट्सवर, रेंडरिंगपूर्वी कॉल केली जाते. स्टेट अपडेट करण्यासाठी याने एक ऑब्जेक्ट परत करावा, किंवा नवीन प्रॉप्ससाठी कोणतेही स्टेट अपडेट आवश्यक नसल्यासnullपरत करावे. ही मेथड प्रॉप बदलांवर आधारित अंदाजे स्टेट अपडेट्सना प्रोत्साहन देते.render(): आवश्यक मेथड जी रेंडर करण्यासाठी JSX परत करते. ही प्रॉप्स आणि स्टेटचे एक शुद्ध फंक्शन असावी.componentDidMount(): कंपोनेंट माउंट झाल्यानंतर (ट्रीमध्ये समाविष्ट झाल्यावर) लगेच कॉल केली जाते. डेटा मिळवणे किंवा सबस्क्रिप्शन सेट करणे यासारखे साइड इफेक्ट्स करण्यासाठी ही एक चांगली जागा आहे.shouldComponentUpdate(nextProps, nextState): नवीन प्रॉप्स किंवा स्टेट मिळाल्यावर रेंडरिंगपूर्वी कॉल केली जाते. हे अनावश्यक री-रेंडर्स टाळून कार्यक्षमता ऑप्टिमाइझ करण्याची परवानगी देते. कंपोनेंट अपडेट व्हायचा असेल तरtrueपरत करावे, अन्यथाfalseपरत करावे.getSnapshotBeforeUpdate(prevProps, prevState): DOM अपडेट होण्यापूर्वी लगेच कॉल केली जाते. DOM बदलण्यापूर्वी त्यातून माहिती (उदा. स्क्रोल पोझिशन) कॅप्चर करण्यासाठी उपयुक्त. परत केलेले मूल्यcomponentDidUpdate()ला पॅरामीटर म्हणून पास केले जाईल.componentDidUpdate(prevProps, prevState, snapshot): अपडेट झाल्यानंतर लगेच कॉल केली जाते. कंपोनेंट अपडेट झाल्यानंतर DOM ऑपरेशन्स करण्यासाठी ही एक चांगली जागा आहे.componentWillUnmount(): कंपोनेंट अनमाउंट आणि नष्ट होण्यापूर्वी लगेच कॉल केली जाते. इव्हेंट लिसनर्स काढणे किंवा नेटवर्क रिक्वेस्ट रद्द करणे यासारखे रिसोर्सेस स्वच्छ करण्यासाठी ही एक चांगली जागा आहे.static getDerivedStateFromError(error): रेंडरिंग दरम्यान त्रुटी आल्यानंतर कॉल केली जाते. ही त्रुटीला आर्गुमेंट म्हणून स्वीकारते आणि स्टेट अपडेट करण्यासाठी एक मूल्य परत करावे. हे कंपोनेंटला फॉलबॅक UI प्रदर्शित करण्याची परवानगी देते.componentDidCatch(error, info): डिसेंडंट कंपोनेंटमध्ये रेंडरिंग दरम्यान त्रुटी आल्यानंतर कॉल केली जाते. ही त्रुटी आणि कंपोनेंट स्टॅक माहितीला आर्गुमेंट्स म्हणून स्वीकारते. एरर रिपोर्टिंग सेवेला त्रुटी लॉग करण्यासाठी ही एक चांगली जागा आहे.
लाइफसायकल मेथड्सचे प्रत्यक्ष उदाहरण
एका अशा कंपोनेंटचा विचार करा जो माउंट झाल्यावर API मधून डेटा आणतो आणि त्याचे प्रॉप्स बदलल्यावर डेटा अपडेट करतो:
class DataFetcher extends React.Component {
constructor(props) {
super(props);
this.state = { data: null };
}
componentDidMount() {
this.fetchData();
}
componentDidUpdate(prevProps) {
if (this.props.url !== prevProps.url) {
this.fetchData();
}
}
fetchData = async () => {
try {
const response = await fetch(this.props.url);
const data = await response.json();
this.setState({ data });
} catch (error) {
console.error('Error fetching data:', error);
}
};
render() {
if (!this.state.data) {
return <p>Loading...</p>;
}
return <div>{this.state.data.message}</div>;
}
}
या उदाहरणात:
componentDidMount()कंपोनेंट पहिल्यांदा माउंट झाल्यावर डेटा आणते.componentDidUpdate()जरurlप्रॉप बदलला तर पुन्हा डेटा आणते.render()मेथड डेटा आणला जात असताना लोडिंग संदेश दाखवते आणि डेटा उपलब्ध झाल्यावर तो रेंडर करते.
लाइफसायकल मेथड्स आणि एरर हँडलिंग
रिॲक्ट रेंडरिंग दरम्यान होणाऱ्या त्रुटी हाताळण्यासाठी लाइफसायकल मेथड्स देखील प्रदान करते:
static getDerivedStateFromError(error): रेंडरिंग दरम्यान त्रुटी आल्यानंतर कॉल केली जाते. ही त्रुटीला आर्गुमेंट म्हणून स्वीकारते आणि स्टेट अपडेट करण्यासाठी एक मूल्य परत करावे. हे कंपोनेंटला फॉलबॅक UI प्रदर्शित करण्याची परवानगी देते.componentDidCatch(error, info): डिसेंडंट कंपोनेंटमध्ये रेंडरिंग दरम्यान त्रुटी आल्यानंतर कॉल केली जाते. ही त्रुटी आणि कंपोनेंट स्टॅक माहितीला आर्गुमेंट्स म्हणून स्वीकारते. एरर रिपोर्टिंग सेवेला त्रुटी लॉग करण्यासाठी ही एक चांगली जागा आहे.
या मेथड्समुळे तुम्ही त्रुटींना व्यवस्थित हाताळू शकता आणि तुमच्या ॲप्लिकेशनला क्रॅश होण्यापासून वाचवू शकता. उदाहरणार्थ, तुम्ही वापरकर्त्याला त्रुटी संदेश दाखवण्यासाठी getDerivedStateFromError() वापरू शकता आणि सर्व्हरवर त्रुटी लॉग करण्यासाठी componentDidCatch() वापरू शकता.
हुक्स आणि फंक्शनल कंपोनेंट्स
रिॲक्ट १६.८ मध्ये सादर केलेले रिॲक्ट हुक्स (Hooks), फंक्शनल कंपोनेंट्समध्ये स्टेट आणि इतर रिॲक्ट वैशिष्ट्ये वापरण्याचा एक मार्ग प्रदान करतात. फंक्शनल कंपोनेंट्समध्ये क्लास कंपोनेंट्ससारख्या लाइफसायकल मेथड्स नसल्या तरी, हुक्स समान कार्यक्षमता प्रदान करतात.
useState(): तुम्हाला फंक्शनल कंपोनेंट्समध्ये स्टेट जोडण्याची परवानगी देतो.useEffect(): तुम्हाला फंक्शनल कंपोनेंट्समध्ये साइड इफेक्ट्स करण्याची परवानगी देतो, जेcomponentDidMount(),componentDidUpdate(), आणिcomponentWillUnmount()सारखेच आहे.useContext(): तुम्हाला रिॲक्ट कॉन्टेक्स्टमध्ये प्रवेश करण्याची परवानगी देतो.useReducer(): तुम्हाला रिड्यूसर फंक्शन वापरून क्लिष्ट स्टेट व्यवस्थापित करण्याची परवानगी देतो.useCallback(): एका फंक्शनची मेमोइज्ड आवृत्ती परत करतो जी केवळ अवलंबित्व बदलल्यास बदलते.useMemo(): एक मेमोइज्ड मूल्य परत करतो जे केवळ अवलंबित्व बदलल्यास पुन्हा गणना करते.useRef(): तुम्हाला रेंडर्स दरम्यान मूल्ये टिकवून ठेवण्याची परवानगी देतो.useImperativeHandle():refवापरताना पालक कंपोनेंट्सना उघड होणारे इन्स्टन्स व्हॅल्यू सानुकूलित करतो.useLayoutEffect():useEffectची एक आवृत्ती जी सर्व DOM म्युटेशननंतर सिंक्रोनसपणे फायर होते.useDebugValue(): रिॲक्ट डेव्हटूल्समध्ये कस्टम हुक्ससाठी मूल्य प्रदर्शित करण्यासाठी वापरले जाते.
useEffect हुकचे उदाहरण
फंक्शनल कंपोनेंटमध्ये डेटा आणण्यासाठी तुम्ही useEffect() हुक कसे वापरू शकता ते येथे आहे:
import React, { useState, useEffect } from 'react';
function DataFetcher({ url }) {
const [data, setData] = useState(null);
useEffect(() => {
async function fetchData() {
try {
const response = await fetch(url);
const json = await response.json();
setData(json);
} catch (error) {
console.error('Error fetching data:', error);
}
}
fetchData();
}, [url]); // केवळ URL बदलल्यास इफेक्ट पुन्हा चालवा
if (!data) {
return <p>Loading...</p>;
}
return <div>{data.message}</div>;
}
या उदाहरणात:
useEffect()कंपोनेंट पहिल्यांदा रेंडर झाल्यावर आणि जेव्हाurlप्रॉप बदलते तेव्हा डेटा आणते.useEffect()चा दुसरा आर्गुमेंट अवलंबित्व (dependencies) चा एक ॲरे आहे. जर यातील कोणतेही अवलंबित्व बदलले, तर इफेक्ट पुन्हा चालवला जाईल.useState()हुक कंपोनेंटचे स्टेट व्यवस्थापित करण्यासाठी वापरले जाते.
रिॲक्ट रेंडरिंग कार्यक्षमता ऑप्टिमाइझ करणे
कार्यक्षम रिॲक्ट ॲप्लिकेशन्स तयार करण्यासाठी कार्यक्षम रेंडरिंग महत्त्वाचे आहे. रेंडरिंग कार्यक्षमता ऑप्टिमाइझ करण्यासाठी येथे काही तंत्रे आहेत:
१. अनावश्यक री-रेंडर्स टाळणे
रेंडरिंग कार्यक्षमता ऑप्टिमाइझ करण्याचा एक सर्वात प्रभावी मार्ग म्हणजे अनावश्यक री-रेंडर्स टाळणे. री-रेंडर्स टाळण्यासाठी येथे काही तंत्रे आहेत:
React.memo()वापरणे:React.memo()एक हायर-ऑर्डर कंपोनेंट आहे जो फंक्शनल कंपोनेंटला मेमोइझ करतो. तो फक्त त्याचे प्रॉप्स बदलल्यासच कंपोनेंटला पुन्हा रेंडर करतो.shouldComponentUpdate()लागू करणे: क्लास कंपोनेंट्समध्ये, तुम्ही प्रॉप किंवा स्टेट बदलांवर आधारित री-रेंडर्स टाळण्यासाठीshouldComponentUpdate()लाइफसायकल मेथड लागू करू शकता.useMemo()आणिuseCallback()वापरणे: हे हुक्स मूल्ये आणि फंक्शन्स मेमोइझ करण्यासाठी वापरले जाऊ शकतात, ज्यामुळे अनावश्यक री-रेंडर्स टळतात.- अपरिवर्तनीय (immutable) डेटा स्ट्रक्चर्स वापरणे: अपरिवर्तनीय डेटा स्ट्रक्चर्स हे सुनिश्चित करतात की डेटामधील बदल विद्यमान ऑब्जेक्ट्समध्ये बदल करण्याऐवजी नवीन ऑब्जेक्ट्स तयार करतात. यामुळे बदल शोधणे आणि अनावश्यक री-रेंडर्स टाळणे सोपे होते.
२. कोड-स्प्लिटिंग
कोड-स्प्लिटिंग म्हणजे तुमच्या ॲप्लिकेशनला लहान भागांमध्ये (chunks) विभागण्याची प्रक्रिया, जे मागणीनुसार लोड केले जाऊ शकतात. यामुळे तुमच्या ॲप्लिकेशनचा सुरुवातीचा लोड वेळ लक्षणीयरीत्या कमी होऊ शकतो.
रिॲक्ट कोड-स्प्लिटिंग लागू करण्याचे अनेक मार्ग प्रदान करते:
React.lazy()आणिSuspenseवापरणे: ही वैशिष्ट्ये तुम्हाला कंपोनेंट्स डायनॅमिकपणे इम्पोर्ट करण्याची परवानगी देतात, फक्त गरज असेल तेव्हाच त्यांना लोड करतात.- डायनॅमिक इम्पोर्ट्स वापरणे: तुम्ही मागणीनुसार मॉड्यूल्स लोड करण्यासाठी डायनॅमिक इम्पोर्ट्स वापरू शकता.
३. लिस्ट व्हर्च्युअलायझेशन
मोठ्या लिस्ट्स रेंडर करताना, सर्व आयटम्स एकाच वेळी रेंडर करणे धीमे असू शकते. लिस्ट व्हर्च्युअलायझेशन तंत्र तुम्हाला फक्त स्क्रीनवर सध्या दिसणारे आयटम्स रेंडर करण्याची परवानगी देतात. जसा वापरकर्ता स्क्रोल करतो, नवीन आयटम्स रेंडर होतात आणि जुने आयटम्स अनमाउंट होतात.
अनेक लायब्ररीज आहेत ज्या लिस्ट व्हर्च्युअलायझेशन कंपोनेंट्स प्रदान करतात, जसे की:
react-windowreact-virtualized
४. इमेजेस ऑप्टिमाइझ करणे
इमेजेस अनेकदा कार्यक्षमतेच्या समस्यांचे एक मोठे स्रोत असू शकतात. इमेजेस ऑप्टिमाइझ करण्यासाठी येथे काही टिपा आहेत:
- ऑप्टिमाइझ केलेले इमेज फॉरमॅट्स वापरा: चांगल्या कॉम्प्रेशन आणि गुणवत्तेसाठी WebP सारखे फॉरमॅट्स वापरा.
- इमेजेसचा आकार बदला: त्यांच्या डिस्प्ले आकारासाठी योग्य परिमाणांमध्ये इमेजेसचा आकार बदला.
- इमेजेस लेझी लोड करा: इमेजेस फक्त स्क्रीनवर दिसतील तेव्हाच लोड करा.
- CDN वापरा: तुमच्या वापरकर्त्यांच्या भौगोलिकदृष्ट्या जवळ असलेल्या सर्व्हरवरून इमेजेस सर्व्ह करण्यासाठी कंटेंट डिलिव्हरी नेटवर्क (CDN) वापरा.
५. प्रोफाइलिंग आणि डीबगिंग
रिॲक्ट रेंडरिंग कार्यक्षमतेचे प्रोफाइलिंग आणि डीबगिंग करण्यासाठी साधने प्रदान करते. रिॲक्ट प्रोफाइलर तुम्हाला रेंडरिंग कार्यक्षमता रेकॉर्ड आणि विश्लेषण करण्याची परवानगी देतो, ज्यामुळे कार्यक्षमतेत अडथळा आणणारे कंपोनेंट्स ओळखता येतात.
रिॲक्ट डेव्हटूल्स ब्राउझर एक्स्टेंशन रिॲक्ट कंपोनेंट्स, स्टेट आणि प्रॉप्स तपासण्यासाठी साधने प्रदान करते.
व्यावहारिक उदाहरणे आणि सर्वोत्तम पद्धती
उदाहरण: एका फंक्शनल कंपोनेंटला मेमोइझ करणे
एका साध्या फंक्शनल कंपोनेंटचा विचार करा जो वापरकर्त्याचे नाव दाखवतो:
function UserProfile({ user }) {
console.log('Rendering UserProfile');
return <div>{user.name}</div>;
}
या कंपोनेंटला अनावश्यकपणे पुन्हा रेंडर होण्यापासून रोखण्यासाठी, तुम्ही React.memo() वापरू शकता:
import React from 'react';
const UserProfile = React.memo(({ user }) => {
console.log('Rendering UserProfile');
return <div>{user.name}</div>;
});
आता, UserProfile फक्त user प्रॉप बदलल्यासच पुन्हा रेंडर होईल.
उदाहरण: useCallback() वापरणे
एका कंपोनेंटचा विचार करा जो चाइल्ड कंपोनेंटला कॉलबॅक फंक्शन पास करतो:
import React, { useState } from 'react';
function ParentComponent() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
};
return (
<div>
<ChildComponent onClick={handleClick} />
<p>Count: {count}</p>
</div>
);
}
function ChildComponent({ onClick }) {
console.log('Rendering ChildComponent');
return <button onClick={onClick}>Click me</button>;
}
या उदाहरणात, ParentComponent च्या प्रत्येक रेंडरवर handleClick फंक्शन पुन्हा तयार केले जाते. यामुळे ChildComponent अनावश्यकपणे पुन्हा रेंडर होते, जरी त्याचे प्रॉप्स बदलले नसले तरीही.
हे टाळण्यासाठी, तुम्ही handleClick फंक्शन मेमोइझ करण्यासाठी useCallback() वापरू शकता:
import React, { useState, useCallback } from 'react';
function ParentComponent() {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount(count + 1);
}, [count]); // केवळ काउंट बदलल्यास फंक्शन पुन्हा तयार करा
return (
<div>
<ChildComponent onClick={handleClick} />
<p>Count: {count}</p>
</div>
);
}
function ChildComponent({ onClick }) {
console.log('Rendering ChildComponent');
return <button onClick={onClick}>Click me</button>;
}
आता, handleClick फंक्शन फक्त count स्टेट बदलल्यासच पुन्हा तयार केले जाईल.
उदाहरण: useMemo() वापरणे
एका कंपोनेंटचा विचार करा जो त्याच्या प्रॉप्सवर आधारित एक व्युत्पन्न मूल्य (derived value) गणना करतो:
import React, { useState } from 'react';
function MyComponent({ items }) {
const [filter, setFilter] = useState('');
const filteredItems = items.filter(item => item.name.includes(filter));
return (
<div>
<input type="text" value={filter} onChange={e => setFilter(e.target.value)} />
<ul>
{filteredItems.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
}
या उदाहरणात, MyComponent च्या प्रत्येक रेंडरवर filteredItems ॲरेची पुन्हा गणना केली जाते, जरी items प्रॉप बदलला नसला तरीही. जर items ॲरे मोठा असेल तर हे अकार्यक्षम असू शकते.
हे टाळण्यासाठी, तुम्ही filteredItems ॲरे मेमोइझ करण्यासाठी useMemo() वापरू शकता:
import React, { useState, useMemo } from 'react';
function MyComponent({ items }) {
const [filter, setFilter] = useState('');
const filteredItems = useMemo(() => {
return items.filter(item => item.name.includes(filter));
}, [items, filter]); // केवळ आयटम्स किंवा फिल्टर बदलल्यास पुन्हा गणना करा
return (
<div>
<input type="text" value={filter} onChange={e => setFilter(e.target.value)} />
<ul>
{filteredItems.map(item => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
);
}
आता, filteredItems ॲरेची पुन्हा गणना फक्त items प्रॉप किंवा filter स्टेट बदलल्यासच केली जाईल.
निष्कर्ष
रिॲक्टची रेंडरिंग प्रक्रिया आणि कंपोनेंट लाइफसायकल समजून घेणे, कार्यक्षम आणि देखरेख करण्यायोग्य ॲप्लिकेशन्स तयार करण्यासाठी आवश्यक आहे. मेमोइझेशन, कोड-स्प्लिटिंग आणि लिस्ट व्हर्च्युअलायझेशन यासारख्या तंत्रांचा वापर करून, डेव्हलपर्स रेंडरिंग कार्यक्षमता ऑप्टिमाइझ करू शकतात आणि एक सहज आणि प्रतिसाद देणारा वापरकर्ता अनुभव तयार करू शकतात. हुक्सच्या परिचयामुळे, फंक्शनल कंपोनेंट्समध्ये स्टेट आणि साइड इफेक्ट्स व्यवस्थापित करणे अधिक सोपे झाले आहे, ज्यामुळे रिॲक्ट डेव्हलपमेंटची लवचिकता आणि शक्ती आणखी वाढली आहे. तुम्ही एक लहान वेब ॲप्लिकेशन तयार करत असाल किंवा एक मोठी एंटरप्राइझ सिस्टीम, रिॲक्टच्या रेंडरिंग संकल्पनांवर प्रभुत्व मिळवणे तुमची उच्च-गुणवत्तेचे यूजर इंटरफेस तयार करण्याची क्षमता लक्षणीयरीत्या सुधारेल.